import java.util.HashMap;

public class LearnTopicModel {

	public static HashMap<String,String> arguments;
	
	public static void main(String[] args) throws Exception {
		arguments = new HashMap<String,String>();
		
		for (int i = 0; i < args.length; i += 2) {
			arguments.put(args[i], args[i+1]);
		}

		String model = arguments.get("-model");
		String filename = arguments.get("-input");
		
		if (model == null) {
			System.out.println("No model specified.");
			return;
		}
		
		TopicModel topicModel = null;


		
		 if (model.equals("ccmixauthortopic")) {
			if (!arguments.containsKey("-Z")) {
				System.out.println("Must specify number of topics using -Z");
				return;
			}
			
			int Z = Integer.parseInt(arguments.get("-Z"));
			
			double alpha = 1.0;
			double beta = 0.01;
			double delta = 0.01;
			double gamma0 = 1.0;
			double gamma1 = 1.0;

			if (arguments.containsKey("-alpha")) 
				alpha = Double.parseDouble(arguments.get("-alpha"));
			if (arguments.containsKey("-beta")) 
				beta = Double.parseDouble(arguments.get("-beta"));
			if (arguments.containsKey("-delta")) 
				delta = Double.parseDouble(arguments.get("-delta"));
			if (arguments.containsKey("-gamma0")) 
				gamma0 = Double.parseDouble(arguments.get("-gamma0"));
			if (arguments.containsKey("-gamma1")) 
				gamma1 = Double.parseDouble(arguments.get("-gamma1"));
			
			topicModel = new ccmixauthortopic(Z, alpha, beta, delta, gamma0, gamma1);
		}
	
		else if (model.equals("ccmixauthortopicClasser")) {
			if (!arguments.containsKey("-Z")) {
				System.out.println("Must specify number of topics using -Z");
				return;
			}
			
			int Z = Integer.parseInt(arguments.get("-Z"));
			
			double alpha = 10.0;
			double beta = 0.01;
			double delta = 0.01;
			double gamma0 = 1.0;
			double gamma1 = 1.0;

			if (arguments.containsKey("-alpha")) 
				alpha = Double.parseDouble(arguments.get("-alpha"));
			if (arguments.containsKey("-beta")) 
				beta = Double.parseDouble(arguments.get("-beta"));
			if (arguments.containsKey("-delta")) 
				delta = Double.parseDouble(arguments.get("-delta"));
			if (arguments.containsKey("-gamma0")) 
				gamma0 = Double.parseDouble(arguments.get("-gamma0"));
			if (arguments.containsKey("-gamma1")) 
				gamma1 = Double.parseDouble(arguments.get("-gamma1"));
			
			topicModel = new ccmixauthortopicClasser(Z, alpha, beta, delta, gamma0, gamma1);
		}
		else if (model.equals("ccmixauthortopiclikelihood")) {
			if (!arguments.containsKey("-Z")) {
				System.out.println("Must specify number of topics using -Z");
				return;
			}
			
			int Z = Integer.parseInt(arguments.get("-Z"));
			
			double alpha =1.0;
			double beta = 0.01;
			double delta = 0.01;
			double gamma0 = 1.0;
			double gamma1 = 1.0;

			if (arguments.containsKey("-alpha")) 
				alpha = Double.parseDouble(arguments.get("-alpha"));
			if (arguments.containsKey("-beta")) 
				beta = Double.parseDouble(arguments.get("-beta"));
			if (arguments.containsKey("-delta")) 
				delta = Double.parseDouble(arguments.get("-delta"));
			if (arguments.containsKey("-gamma0")) 
				gamma0 = Double.parseDouble(arguments.get("-gamma0"));
			if (arguments.containsKey("-gamma1")) 
				gamma1 = Double.parseDouble(arguments.get("-gamma1"));
			
			topicModel = new ccmixauthortopiclikelihood(Z, alpha, beta, delta, gamma0, gamma1);
		}
		else if (model.equals("ccmixauthortopicPerplexity")) {
			if (!arguments.containsKey("-Z")) {
				System.out.println("Must specify number of topics using -Z");
				return;
			}
			
			int Z = Integer.parseInt(arguments.get("-Z"));
			
			double alpha = 2;
			double beta = 0.01;
			double delta = 0.01;
			double gamma0 = 1.0;
			double gamma1 = 1.0;

			if (arguments.containsKey("-alpha")) 
				alpha = Double.parseDouble(arguments.get("-alpha"));
			if (arguments.containsKey("-beta")) 
				beta = Double.parseDouble(arguments.get("-beta"));
			if (arguments.containsKey("-delta")) 
				delta = Double.parseDouble(arguments.get("-delta"));
			if (arguments.containsKey("-gamma0")) 
				gamma0 = Double.parseDouble(arguments.get("-gamma0"));
			if (arguments.containsKey("-gamma1")) 
				gamma1 = Double.parseDouble(arguments.get("-gamma1"));
			
			topicModel = new ccmixauthortopicPerplexity(Z, alpha, beta, delta, gamma0, gamma1);
			//TopicModel.alist = (ccmixauthortopicPerplexity)topicModel;
		}
		else if (model.equals("UtmRwr_Pre")) {
			if (!arguments.containsKey("-Z")) {
				System.out.println("Must specify number of topics using -Z");
				return;
			}
			
			int Z = Integer.parseInt(arguments.get("-Z"));
			
			double alpha = 1.0;
			double beta = 0.01;

			if (arguments.containsKey("-alpha")) 
				alpha = Double.parseDouble(arguments.get("-alpha"));
			if (arguments.containsKey("-beta")) 
				beta = Double.parseDouble(arguments.get("-beta"));
			
			topicModel = new UtmRwr_Pre(Z, alpha, beta );
		}
		else if (model.equals("UtmRwr_Model")) {
			if (!arguments.containsKey("-Z")) {
				System.out.println("Must specify number of topics using -Z");
				return;
			}
			
			int Z = Integer.parseInt(arguments.get("-Z"));
			
			double alpha = 0.833333;
			double beta = 0.01;

			if (arguments.containsKey("-alpha")) 
				alpha = Double.parseDouble(arguments.get("-alpha"));
			if (arguments.containsKey("-beta")) 
				beta = Double.parseDouble(arguments.get("-beta"));
			
			topicModel = new UtmRwr_Model(Z, alpha, beta );
		}
		else if (model.equals("noccmixauthortopiclikelihood")) {
			if (!arguments.containsKey("-Z")) {
				System.out.println("Must specify number of topics using -Z");
				return;
			}
			
			int Z = Integer.parseInt(arguments.get("-Z"));
			
			double alpha = 1.0;
			double beta = 0.01;

			if (arguments.containsKey("-alpha")) 
				alpha = Double.parseDouble(arguments.get("-alpha"));
			if (arguments.containsKey("-beta")) 
				beta = Double.parseDouble(arguments.get("-beta"));
			
			topicModel = new noccmixauthortopiclikelihood(Z, alpha, beta );
		}
		else if (model.equals("UTMforRecommendation")) {
			if (!arguments.containsKey("-Z")) {
				System.out.println("Must specify number of topics using -Z");
				return;
			}
			
			int Z = Integer.parseInt(arguments.get("-Z"));
			
			double alpha = 1.0;
			double beta = 0.01;

			if (arguments.containsKey("-alpha")) 
				alpha = Double.parseDouble(arguments.get("-alpha"));
			if (arguments.containsKey("-beta")) 
				beta = Double.parseDouble(arguments.get("-beta"));
			
			topicModel = new UTMforRecommendation(Z, alpha, beta );
		}
		else if (model.equals("noccmixauthortopicPerplexity")) {
			if (!arguments.containsKey("-Z")) {
				System.out.println("Must specify number of topics using -Z");
				return;
			}
			
			int Z = Integer.parseInt(arguments.get("-Z"));
			
			double alpha = 1.0;
			double beta = 0.01;

			if (arguments.containsKey("-alpha")) 
				alpha = Double.parseDouble(arguments.get("-alpha"));
			if (arguments.containsKey("-beta")) 
				beta = Double.parseDouble(arguments.get("-beta"));
			
			topicModel = new noccmixauthortopicPerplexity(Z, alpha, beta );
		}
		else if (model.equals("noccmixauthortopicprediction")) {
			if (!arguments.containsKey("-Z")) {
				System.out.println("Must specify number of topics using -Z");
				return;
			}
			
			int Z = Integer.parseInt(arguments.get("-Z"));
			
			double alpha = 1.0;
			double beta = 0.01;

			if (arguments.containsKey("-alpha")) 
				alpha = Double.parseDouble(arguments.get("-alpha"));
			if (arguments.containsKey("-beta")) 
				beta = Double.parseDouble(arguments.get("-beta"));
			
			topicModel = new noccmixauthortopicprediction(Z, alpha, beta );
		}
		else if (model.equals("ccmixauthortopicprediction")) {
			if (!arguments.containsKey("-Z")) {
				System.out.println("Must specify number of topics using -Z");
				return;
			}
			
			int Z = Integer.parseInt(arguments.get("-Z"));
			
			double alpha = 1.0;
			double beta = 0.01;
			double delta = 0.01;
			double gamma0 = 1.0;
			double gamma1 = 1.0;

			if (arguments.containsKey("-alpha")) 
				alpha = Double.parseDouble(arguments.get("-alpha"));
			if (arguments.containsKey("-beta")) 
				beta = Double.parseDouble(arguments.get("-beta"));
			if (arguments.containsKey("-delta")) 
				delta = Double.parseDouble(arguments.get("-delta"));
			if (arguments.containsKey("-gamma0")) 
				gamma0 = Double.parseDouble(arguments.get("-gamma0"));
			if (arguments.containsKey("-gamma1")) 
				gamma1 = Double.parseDouble(arguments.get("-gamma1"));
			
			topicModel = new ccmixauthortopicprediction(Z, alpha, beta, delta, gamma0, gamma1);
		}
		else if (model.equals("ccmixauthor")) {
			double beta = 0.01;
			double delta = 0.01;
			double gamma0 = 1.0;
			double gamma1 = 1.0;

			if (arguments.containsKey("-beta")) 
				beta = Double.parseDouble(arguments.get("-beta"));
			if (arguments.containsKey("-delta")) 
				delta = Double.parseDouble(arguments.get("-delta"));
			if (arguments.containsKey("-gamma0")) 
				gamma0 = Double.parseDouble(arguments.get("-gamma0"));
			if (arguments.containsKey("-gamma1")) 
				gamma1 = Double.parseDouble(arguments.get("-gamma1"));
			
			topicModel = new ccmixauthor(beta, delta, gamma0, gamma1);
		}
		else if (model.equals("noccmixauthor")) {
			    double beta = 0.01;
	
                if (arguments.containsKey("-beta")) 
				beta = Double.parseDouble(arguments.get("-beta"));
			    topicModel = new noccmixauthor(beta);
		}
		else if (model.equals("noccmixauthorlikelihood")) {
		    double beta = 0.01;

            if (arguments.containsKey("-beta")) 
			beta = Double.parseDouble(arguments.get("-beta"));
		    topicModel = new noccmixauthorlikelihood(beta);
	}
		else if (model.equals("noccmixauthorPerplexity")) {
		    double beta = 0.01;

            if (arguments.containsKey("-beta")) 
			beta = Double.parseDouble(arguments.get("-beta"));
		    topicModel = new noccmixauthorPerplexity(beta);
	}
		else if (model.equals("noccmixauthorprediction")) {
		    double beta = 0.01;

            if (arguments.containsKey("-beta")) 
			beta = Double.parseDouble(arguments.get("-beta"));
		    topicModel = new noccmixauthorprediction(beta);
	}
		else if (model.equals("ccmixauthorprediction")) {
			double beta = 0.01;
			double delta = 0.01;
			double gamma0 = 1.0;
			double gamma1 = 1.0;

			if (arguments.containsKey("-beta")) 
				beta = Double.parseDouble(arguments.get("-beta"));
			if (arguments.containsKey("-delta")) 
				delta = Double.parseDouble(arguments.get("-delta"));
			if (arguments.containsKey("-gamma0")) 
				gamma0 = Double.parseDouble(arguments.get("-gamma0"));
			if (arguments.containsKey("-gamma1")) 
				gamma1 = Double.parseDouble(arguments.get("-gamma1"));
			
			topicModel = new ccmixauthorprediction(beta, delta, gamma0, gamma1);
		}
		else if (model.equals("ccmixauthorlikelihood")) {
			double beta = 0.01;
			double delta = 0.01;
			double gamma0 = 1.0;
			double gamma1 = 1.0;

			if (arguments.containsKey("-beta")) 
				beta = Double.parseDouble(arguments.get("-beta"));
			if (arguments.containsKey("-delta")) 
				delta = Double.parseDouble(arguments.get("-delta"));
			if (arguments.containsKey("-gamma0")) 
				gamma0 = Double.parseDouble(arguments.get("-gamma0"));
			if (arguments.containsKey("-gamma1")) 
				gamma1 = Double.parseDouble(arguments.get("-gamma1"));
			
			topicModel = new ccmixauthorlikelihood(beta, delta, gamma0, gamma1);
		}
		else if (model.equals("ccmixauthorPerplexity")) {
			double beta = 0.01;
			double delta = 0.01;
			double gamma0 = 1.0;
			double gamma1 = 1.0;

			if (arguments.containsKey("-beta")) 
				beta = Double.parseDouble(arguments.get("-beta"));
			if (arguments.containsKey("-delta")) 
				delta = Double.parseDouble(arguments.get("-delta"));
			if (arguments.containsKey("-gamma0")) 
				gamma0 = Double.parseDouble(arguments.get("-gamma0"));
			if (arguments.containsKey("-gamma1")) 
				gamma1 = Double.parseDouble(arguments.get("-gamma1"));
			
			topicModel = new ccmixauthorPerplexity(beta, delta, gamma0, gamma1);
		}
		else if (model.equals("tam")) {
			if (!arguments.containsKey("-Z")) {
				System.out.println("Must specify number of topics using -Z");
				return;
			}
			if (!arguments.containsKey("-Y")) {
				System.out.println("Must specify number of aspects using -Y");
				return;
			}
			
			int Z = Integer.parseInt(arguments.get("-Z"));
			int Y = Integer.parseInt(arguments.get("-Y"));
			
			double alpha = 0.1;
			double beta = 0.1;
			double omega = 0.01;
			double gamma0 = 1.0;
			double gamma1 = 1.0;
			double delta0 = 10.0;
			double delta1 = 10.0;
			double labelPrior = 0;

			if (arguments.containsKey("-alpha")) 
				alpha = Double.parseDouble(arguments.get("-alpha"));
			if (arguments.containsKey("-beta")) 
				beta = Double.parseDouble(arguments.get("-beta"));
			if (arguments.containsKey("-omega")) 
				omega = Double.parseDouble(arguments.get("-omega"));
			if (arguments.containsKey("-gamma0")) 
				gamma0 = Double.parseDouble(arguments.get("-gamma0"));
			if (arguments.containsKey("-gamma1")) 
				gamma1 = Double.parseDouble(arguments.get("-gamma1"));
			if (arguments.containsKey("-delta0")) 
				delta0 = Double.parseDouble(arguments.get("-delta0"));
			if (arguments.containsKey("-delta1")) 
				delta1 = Double.parseDouble(arguments.get("-delta1"));
			if (arguments.containsKey("-labelPrior")) 
				labelPrior = Double.parseDouble(arguments.get("-labelPrior"));
			
			topicModel = new TAM(Z, Y, alpha, beta, omega, gamma0, gamma1, delta0, delta1, labelPrior);
			
		}
		else {
			System.out.println("Invalid model specification. Options: lda | cclda | tam");
			return;
		}
		
		int iters = 100;
		if (arguments.containsKey("-iters")) 
			iters = Integer.parseInt(arguments.get("-iters"));
		
		topicModel.run(iters, filename);
	}

}
